﻿using System.Configuration;
using System.Xml;
using System.Collections;
using RAP.Framework.Libary.Utils;
using System.IO;
using System;

namespace RAP.Framework.Libary.Configuration
{
    /// <summary>
    /// 站点配置管理
    /// </summary>
    public class ConfigurationManager : DynamicHashtable, IConfigurationManager
    {
        private static IConfigurationManager _instance = null;
        public static string CONFIG_SECTION_NAME = "ConfigureManager";
        public static string CACHE_KEY = "ConfigurationCache";

        /// <summary>
        /// 获取站点配置管理的全局单太实例，键值对对象
        /// </summary>
        public static IConfigurationManager AppSettings
        {
            get
            {
                if ( _instance == null )
                {
                    _instance = new ConfigurationManager();
                }
                return _instance;
            }
        }

        private ConfigurationManager ( )
        {
            if ( _instance != null )
            {
                throw new Exception( "ConfigurationManager已经实例化！" );
            }
        }

        /// <summary>
        /// 当站点参数发生变更时的事件
        /// </summary>
        public event EventHandler OnSettingsChangedEvent;

        /// <summary>
        /// 当站点参数文件发生变更时的事件
        /// </summary>
        public event EventHandler OnRefreshingConfigEvent;

        /// <summary>
        /// 发生错误的事件
        /// </summary>
        public event Action<Exception, IDictionary> OnErrorEvent;

        /// <summary>
        /// 读取.json配置
        /// </summary>
        /// <param name="file">相对路径</param>
        /// <param name="enableWatcher">是否开启文件变更检测</param>
        /// <returns></returns>
        public IConfigurationManager Config ( string file, bool enableWatcher = true )
        {
            file.MapPath().ReadJSON( this );
            if ( enableWatcher )
            {
                //开启文件监视
                FileInfo fileInfo = file.FileInfo();

                FileSystemWatcherUtils.RegisterWatcher( fileInfo.DirectoryName
                    , fileInfo.Name
                    , NotifyFilters.LastWrite | NotifyFilters.CreationTime | NotifyFilters.Size
                    , ( watcherInfo, eventArgs ) =>
                {
                    if ( eventArgs.ChangeType == WatcherChangeTypes.Changed )
                    {
                        if ( this.OnRefreshingConfigEvent != null )
                        {
                            this.OnRefreshingConfigEvent( this, new EventArgs() );
                        }
                        try
                        {
                            eventArgs.FullPath.ReadJSON( this, true );//文件发生更改时重新读取配置文件
                            if ( this.OnSettingsChangedEvent != null )
                            {
                                this.OnSettingsChangedEvent( this, new EventArgs() );
                            }
                        }
                        catch ( Exception e )
                        {
                            if ( this.OnErrorEvent != null )
                            {
                                this.OnErrorEvent( e, new Hashtable() { { "File", eventArgs.FullPath.UnMapPath() } } );
                            }
                        }
                        finally { }
                    }
                } );
            }
            return this;
        }

    }
}
